package your.rfgui.extgui.controller.tree;

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import your.rfgui.extgui.data.intf.DataItem;

/**
 * View controller managing a tree.
 */
public abstract class AbstractTreeController extends BaseTreeController {

   private static final Logger log = Logger.getLogger(AbstractTreeController.class);

   public void populate() {
      log.info("populate");

      /** get selected data item if any, needed to pass over the currently selected view node to the newly build tree */
      DataItem selectedDataItem = getSelectedDataItem();

      /** rebuild all tree nodes */
      rootNodes = new ArrayList<TreeViewNode>();
      List<? extends DataItem> rootDataItems = getViewRootList();
      
      for (DataItem dataItem : rootDataItems) {
         TreeViewNode newViewNode = new TreeViewNode(dataItem);
         /** add top level nodes to root list */
         rootNodes.add(newViewNode);
         if (dataItem.identical(selectedDataItem)) {
            log.info("populate - dataItem match: " + dataItem);
            /** this view node holds the selected data item */
            setSelectedViewNode(newViewNode);
         }
         populate(newViewNode, getViewChildren(dataItem), selectedDataItem);
      }
   }

   private void populate(TreeViewNode treeNodeParent, List<? extends DataItem> dataItems, DataItem selectedDataItem) {
      for (DataItem dataItem : dataItems) {
         TreeViewNode newViewNode = new TreeViewNode(treeNodeParent, dataItem);
         if (dataItem.identical(selectedDataItem)) {
            log.info("populate - dataItem match: " + dataItem);
            /** this view node holds the selected data item */
            setSelectedViewNode(newViewNode);
         }
         populate(newViewNode, getViewChildren(dataItem), selectedDataItem);
      }
   }

   /**
    * Retrieve the root data list to be displayed in the tree view
    */
   abstract List<? extends DataItem> getViewRootList();

   /**
    * Returns the children data item list for the given data item
    */
   abstract List<? extends DataItem> getViewChildren(DataItem dataItem);
}
